﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Modelo_ETdA.Negocio.Analise.Formato;

using Modelo_ETdA.Negocio.Analise.Avaliacao;

namespace Modelo_ETdA.Negocio.Analise.Relatorio
{
    public class RelatorioProfissional : Relatorio
    {
        private List<Avaliacao.Avaliacao> l_aval_pro;
        FormatoAvaliacaoProfissional form_aval_pro;
        private Dictionary<int, List<DistribuicaoRespostas>> mapDivisaoDistResp;
        private Dictionary<int, DistribuicaoRespostas> mapConsidDistResp;

        private Dictionary<int, Boolean> mapDivUsada;


        public RelatorioProfissional(List<Avaliacao.Avaliacao> l_aval_pro, FormatoAvaliacaoProfissional form_aval_pro, AmbienteComercial.AmbienteComercial ambComercial)
            : base(ambComercial)
        {
            this.l_aval_pro = l_aval_pro;
            this.form_aval_pro = form_aval_pro;
            this.mapConsidDistResp = new Dictionary<int, DistribuicaoRespostas>();
            this.mapDivisaoDistResp = new Dictionary<int, List<DistribuicaoRespostas>>();
            this.mapDivUsada = new Dictionary<int, Boolean>();
        }

        private void calcular()
        {

            DistribuicaoRespostas aux_dist;

            int cod_questao;
            int val_resp;
            Questao quest_pro;

            int numRespNeg = 0;
            int numRespSatisf = 0;
            int numRespPos = 0;

            foreach (Avaliacao.Avaliacao aval in l_aval_pro)
            {
                FormularioAvaliacao fa = (FormularioAvaliacao)aval;
                if (!this.mapDivUsada.ContainsKey(fa.CodDivisao)) this.mapDivUsada.Add(fa.CodDivisao, true);

                foreach (Resposta resp in fa.Respostas)
                {
                    cod_questao = resp.CodQuestao;
                    val_resp = resp.ValorResposta;
                    if (val_resp != -1)
                    {
                        quest_pro = form_aval_pro.getQuestao(cod_questao);
                        switch (getSatisf(val_resp, quest_pro.EscalaMin, quest_pro.EscalaMax, quest_pro.MinResposta))
                        {
                            case 0: numRespNeg++; break;
                            case 1: numRespSatisf++; break;
                            case 2: numRespPos++; break;
                        }

                        if (!mapConsidDistResp.ContainsKey(quest_pro.CodConsideracao)) mapConsidDistResp[quest_pro.CodConsideracao] = new DistribuicaoRespostas(0, 0, 0, quest_pro.CodConsideracao);
                        mapConsidDistResp[quest_pro.CodConsideracao].NumRespNeg += numRespNeg;
                        mapConsidDistResp[quest_pro.CodConsideracao].NumRespSatisf += numRespSatisf;
                        mapConsidDistResp[quest_pro.CodConsideracao].NumRespPos += numRespPos;

                        if (!mapDivisaoDistResp.ContainsKey(fa.CodDivisao)) mapDivisaoDistResp[fa.CodDivisao] = new List<DistribuicaoRespostas>();
                        aux_dist = getDistResp(quest_pro.CodConsideracao, mapDivisaoDistResp[fa.CodDivisao]);
                        if (aux_dist == null)
                        {
                            mapDivisaoDistResp[fa.CodDivisao].Add(new DistribuicaoRespostas(numRespNeg, numRespSatisf, numRespPos, quest_pro.CodConsideracao));
                        }
                        else
                        {
                            aux_dist.NumRespNeg += numRespNeg;
                            aux_dist.NumRespSatisf += numRespSatisf;
                            aux_dist.NumRespPos += numRespPos;
                        }
                    }

                    numRespNeg = 0;
                    numRespSatisf = 0;
                    numRespPos = 0;
                }
            }

        }

        private DistribuicaoRespostas getDistResp(int codCons, List<DistribuicaoRespostas> l_d_resp)
        {

            foreach (DistribuicaoRespostas d_resp in l_d_resp)
            {
                if (d_resp.CodConsideracao == codCons) return d_resp;

            }

            return null;
        }

        public List<int> getDivisaoConsPercent(int divisao, int consideracao)
        {
            List<int> ret = new List<int>();
            ret.Add(0); ret.Add(0); ret.Add(0);
            int num_r_neg = 0;
            int num_r_satisf = 0;
            int num_r_pos = 0;

            if (divisao >= 0)
            {
                if (mapDivisaoDistResp.ContainsKey(divisao))
                {
                    foreach (DistribuicaoRespostas d_resp in mapDivisaoDistResp[divisao])
                    {
                        if (d_resp.CodConsideracao == consideracao)
                        {
                            num_r_neg += d_resp.NumRespNeg;
                            num_r_satisf += d_resp.NumRespSatisf;
                            num_r_pos += d_resp.NumRespPos;
                        }
                    }
                }
                else
                {
                    num_r_neg += 0;
                    num_r_satisf += 0;
                    num_r_pos += 0;
                }
            }
            else
            {
                foreach (KeyValuePair<int, List<DistribuicaoRespostas>> par in mapDivisaoDistResp)
                {
                    foreach (DistribuicaoRespostas d_resp in par.Value)
                    {
                        if (d_resp.CodConsideracao == consideracao)
                        {
                            num_r_neg += d_resp.NumRespNeg;
                            num_r_satisf += d_resp.NumRespSatisf;
                            num_r_pos += d_resp.NumRespPos;
                        }
                    }
                }
            }
            int sum_num = num_r_neg + num_r_satisf + num_r_pos;


            ret[0] = (int)(((float)num_r_neg / (float)(num_r_neg + num_r_satisf + num_r_pos)) * 100);
            ret[1] = (int)(((float)num_r_satisf / (float)(num_r_neg + num_r_satisf + num_r_pos)) * 100);
            ret[2] = 100 - ret[0] - ret[1];

            if (ret[2] == 1) ret[2] = 0;
            return ret;
        }
        public int getPiorDivisao(int codCons)
        {
            int i = 0;
            Dictionary<int, int> l_neg = new Dictionary<int, int>();
            int max_neg = -1;
            int div_max = 0;


            foreach (KeyValuePair<int, List<DistribuicaoRespostas>> par in mapDivisaoDistResp)
            {
                l_neg[par.Key] = 0;
                foreach (DistribuicaoRespostas d_resp in par.Value)
                {
                    if (d_resp.CodConsideracao == codCons) l_neg[par.Key] += d_resp.NumRespNeg;

                }
                if (l_neg[par.Key] > max_neg) { max_neg = l_neg[par.Key]; div_max = par.Key; }
            }


            return div_max;
        }

        public override int imprimir()
        {
            calcular();
            Dados.DadosRelatorio da = new Dados.DadosRelatorio();
            return da.imprimirProfissional(this);
        }

        /*
         * 0 -> Negativo
         * 1 -> Satisfatorio
         * 2 -> Positivo
         */
        private int getSatisf(int val_resp, int escalaMin, int escalaMax, int minResp)
        {
            if (val_resp < minResp) return 0;
            if ((val_resp) <= (escalaMax * 0.4)) return 0;
            if ((val_resp) <= (escalaMax * 0.7)) return 1;

            return 2;
        }

        public List<Avaliacao.Avaliacao> L_aval_pro
        {
            get { return l_aval_pro; }
            set { l_aval_pro = value; }
        }

        public FormatoAvaliacaoProfissional Form_aval_pro
        {
            get { return form_aval_pro; }
            set { form_aval_pro = value; }
        }

        public Dictionary<int, List<DistribuicaoRespostas>> MapDivisaoDistResp
        {
            get { return mapDivisaoDistResp; }
            set { mapDivisaoDistResp = value; }
        }

        public Dictionary<int, DistribuicaoRespostas> MapConsidDistResp
        {
            get { return mapConsidDistResp; }
            set { mapConsidDistResp = value; }
        }

        public Dictionary<int, Boolean> MapDivUsada
        {
            get { return mapDivUsada; }
            set { mapDivUsada = value; }
        }
    }
}
